home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / opt.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  27KB  |  648 lines

  1. /*  $VER: vbcc (opt.c) V0.4     */
  2. /*  allgemeine Routinen fuer den Optimizer und Steuerung der einzelnen  */
  3. /*  Laeufe                                                              */
  4.  
  5. #include "opt.h"
  6.  
  7. static char FILE_[]=__FILE__;
  8.  
  9. /*  die naechsten Funktionen sollten evtl. in ic.c                  */
  10.  
  11. /*  Sind use/change-Listen initialisiert?   */
  12. int have_alias;
  13.  
  14. void insert_IC(struct IC *p,struct IC *new)
  15. /*  fuegt new hinter p ein; p darf 0 sein                           */
  16. {
  17.     new->prev=p;
  18.     if(p){ new->next=p->next; p->next=new; }
  19.      else{ new->next=first_ic; first_ic=new; }
  20.     if(new->next) new->next->prev=new; else last_ic=new;
  21.     new->q1.am=new->q2.am=new->z.am=0;
  22. }
  23.  
  24. #ifndef NO_OPTIMIZER
  25.  
  26. int gchanged;   /*  Merker, ob Optimierungslauf etwas geaendert hat */
  27. int norek;      /*  diese Funktion wird nicht rekursiv auf          */
  28. int nocall;     /*  diese Funktion kehrt nicht zum Caller zurueck   */
  29.  
  30. /*  temporary fuer verschiedene Bitvektoren */
  31. unsigned char *tmp;
  32.  
  33. void recalc_offsets(struct flowgraph *fg)
  34. /*  berechnet Offsets fuer auto-Variablen neu und versucht, fuer Variablen, */
  35. /*  die nicht gleichzeitig aktiv sind, den gleichen Platz zu belegen        */
  36. {
  37.     int i,b,*eqto;size_t bsize;zlong *al,*sz;
  38.     unsigned char **used,*tmp,*empty;
  39.     struct IC *p;
  40.     if(DEBUG&1024) printf("recalculating offsets\n");
  41.     if(DEBUG&1024) printf("setting up arrays\n");
  42.     bsize=(basic_blocks+CHAR_BIT-1)/CHAR_BIT;
  43.     if(DEBUG&1024) printf("bsize=%lu\n",(unsigned long)bsize);
  44.     tmp=mymalloc(bsize);
  45.     al=mymalloc(sizeof(*al)*(vcount-rcount));
  46.     eqto=mymalloc(sizeof(int)*(vcount-rcount));
  47.     sz=mymalloc(sizeof(*sz)*(vcount-rcount));
  48.     empty=mymalloc(bsize);
  49.     memset(empty,0,bsize);
  50.     used=mymalloc(sizeof(unsigned char *)*(vcount-rcount));
  51.     /*  Tabelle, welche Variable in welchem Block belegt ist, aufbauen  */
  52.     for(i=0;i<vcount-rcount;i++){
  53.         if(zlleq(l2zl(0L),vilist[i]->offset)&&(vilist[i]->storage_class==AUTO||vilist[i]->storage_class==REGISTER)){
  54.             if(DEBUG&2048) printf("setting up for %s,%ld\n",vilist[i]->identifier,zl2l(vilist[i]->offset));
  55.             used[i]=mymalloc(bsize);
  56.             memset(used[i],0,bsize);
  57.         }else{
  58.             used[i]=0;
  59.         }
  60.         sz[i]=szof(vilist[i]->vtyp);
  61.         al[i]=falign(vilist[i]->vtyp);
  62.         eqto[i]=-1;
  63.     }
  64.     b=0;
  65.     while(fg){
  66.         if(b>=basic_blocks) ierror(0);
  67.         for(i=0;i<vcount-rcount;i++){
  68.             if(used[i]&&(BTST(fg->av_in,i)||BTST(fg->av_out,i))){
  69.                 int r;
  70.                 BSET(used[i],b);
  71.                 for(r=1;r<=MAXR;r++)
  72.                     if(fg->regv[r]&&fg->regv[r]->index==i) BCLR(used[i],b);
  73.             }
  74.         }
  75.         for(p=fg->start;p;p=p->next){
  76.             if((p->q1.flags&(VAR|REG))==VAR){
  77.                 i=p->q1.v->index;
  78.                 if(used[i]){
  79.                     BSET(used[i],b);
  80.                 }
  81.             }
  82.             if((p->q2.flags&(VAR|REG))==VAR){
  83.                 i=p->q2.v->index;
  84.                 if(used[i]){
  85.                     BSET(used[i],b);
  86.                 }
  87.             }
  88.             if((p->z.flags&(VAR|REG))==VAR){
  89.                 i=p->z.v->index;
  90.                 if(used[i]){
  91.                     BSET(used[i],b);
  92.                 }
  93.             }
  94.             if(p==fg->end) break;
  95.         }
  96.         fg=fg->normalout;
  97.         b++;
  98.     }
  99.     /*  schauen, ob Variablen in gleichen Speicher koennen  */
  100.     if(DEBUG&1024) printf("looking for distinct variables\n");
  101.     for(i=0;i<vcount-rcount;i++){
  102.         if(!used[i]||eqto[i]>=0) continue;
  103.         if(!memcmp(used[i],empty,bsize)){ free(used[i]);used[i]=0;continue;}
  104.         for(b=i+1;b<vcount-rcount;b++){
  105.             if(!used[b]||eqto[b]>=0) continue;
  106.             if(DEBUG&2048) printf("comparing %s(%ld) and %s(%ld)\n",vilist[i]->identifier,zl2l(vilist[i]->offset),vilist[b]->identifier,zl2l(vilist[b]->offset));
  107.  
  108.             memcpy(tmp,used[i],bsize);
  109.             bvintersect(tmp,used[b],bsize);
  110.             if(!memcmp(tmp,empty,bsize)){
  111.                 if(DEBUG&1024) printf("memory for %s(%ld) and %s(%ld) equal\n",vilist[i]->identifier,zl2l(vilist[i]->offset),vilist[b]->identifier,zl2l(vilist[b]->offset));
  112.                 eqto[b]=i;
  113.                 if(!zlleq(al[b],al[i])) al[i]=al[b];
  114.                 if(!zlleq(sz[b],sz[i])) sz[i]=sz[b];
  115.                 bvunite(used[i],used[b],bsize);
  116.             }
  117.         }
  118.     }
  119.     if(DEBUG&1024) printf("final recalculating\n");
  120.     max_offset=l2zl(0L);
  121.     for(i=0;i<vcount-rcount;i++){
  122.         if(!used[i]) continue;
  123.         free(used[i]);
  124.         if(DEBUG&2048) printf("adjusting offset for %s,%ld\n",vilist[i]->identifier,zl2l(vilist[i]->offset));
  125.         if(eqto[i]>=0){
  126.             vilist[i]->offset=vilist[eqto[i]]->offset;
  127.             continue;
  128.         }
  129.         vilist[i]->offset=zlmult(zldiv(zladd(max_offset,zlsub(al[i],l2zl(1L))),al[i]),al[i]);
  130.         max_offset=zladd(vilist[i]->offset,sz[i]);
  131.     }
  132.     free(used);
  133.     free(sz);
  134.     free(al);
  135.     free(tmp);
  136.     free(empty);
  137.     free(eqto);
  138. }
  139. void remove_IC_fg(struct flowgraph *g,struct IC *p)
  140. /*  Entfernt IC p und beachtet Flussgraph. Ausserdem werden             */
  141. /*  use/change-Listen freigegeben.                                      */
  142. {
  143.     if(p->q1.am||p->q2.am||p->z.am) ierror(0);
  144.     if(have_alias){
  145.         free(p->use_list);
  146.         free(p->change_list);
  147.     }
  148.     if(g->start==g->end){
  149.         g->start=g->end=0;
  150.     }else{
  151.         if(p==g->end) g->end=p->prev;
  152.         if(p==g->start) g->start=p->next;
  153.     }
  154.     remove_IC(p);
  155. }
  156.  
  157. int peephole(void)
  158. /*  macht alle moeglichen Vereinfachungen/Vereinheitlichungen   */
  159. {
  160.     struct IC *p;struct obj o;int t,c,null,eins,changed,done=0;
  161.     do{
  162.         if(DEBUG&1024) printf("searching for peephole optimizations\n");
  163.         changed=0;ic_count=0;
  164.         p=first_ic;
  165.         while(p){
  166.             c=p->code;
  167.             t=p->typf;
  168.             ic_count++;
  169.             if(c==LABEL&&report_suspicious_loops&&p->next&&p->next->code==BRA&&p->next->typf==t){
  170.               error(208);report_suspicious_loops=0;
  171.             }
  172.             if((p->q1.flags&(KONST|DREFOBJ))==KONST){
  173.                 if((p->q2.flags&KONST)||!p->q2.flags){
  174.                     struct IC *old=p->prev;
  175.                     if(fold(p)){ changed=1; p=old;continue;}
  176.                     p=p->next;continue;
  177.                 }else{
  178.                     if(c==ADD||c==MULT||(c>=OR&&c<=AND)){ /*  const nach rechts   */
  179.                         if(DEBUG&1024){ printf("swapped commutative op:\n");pric2(stdout,p);}
  180.                         o=p->q1;p->q1=p->q2;p->q2=o;
  181.                     }
  182.                 }
  183.             }
  184.             if((p->q2.flags&(KONST|DREFOBJ))==KONST){
  185.             /*  algebraische Optimierungen  */
  186.                 eval_const(&p->q2.val,t);
  187.                 if(zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))&&zdeqto(vdouble,d2zd(0.0))) null=1; else null=0;
  188.                 if(zleqto(vlong,l2zl(1L))&&zuleqto(vulong,ul2zul(1UL))&&zdeqto(vdouble,d2zd(1.0))) eins=1; else eins=0;
  189.                 if(zleqto(vlong,l2zl(-1L))&&zdeqto(vdouble,d2zd(-1.0))) eins=-1;
  190.                 if(eins<0&&(c==MULT||c==DIV)){
  191.                     if(DEBUG&1024){ printf("MULT/DIV with (-1) converted to MINUS:\n");pric2(stdout,p);}
  192.                     p->code=c=MINUS;p->q2.flags=0;
  193.                     changed=1;
  194.                 }
  195. #if 0
  196.                 if(c==SUB){
  197.                 /*  VORSICHT: Das funktioniert bei bestimmten Werten nicht! */
  198.                     if(DEBUG&1024){ printf("SUB converted to ADD:\n");pric2(stdout,p);}
  199.                     p->code=c=ADD; calc(MINUS,t,&p->q2.val,0,&p->q2.val,p);
  200.                     changed=1;
  201.                 }
  202. #endif
  203.                 if((eins>0&&(c==MULT||c==DIV))||(null&&(c==ADD||c==SUB||c==ADDI2P||c==SUBIFP||c==LSHIFT||c==RSHIFT||c==OR||c==XOR))){
  204.                     if(DEBUG&1024){ printf("operation converted to simple assignment:\n");pric2(stdout,p);}
  205.                     if(c==ADDI2P||c==SUBIFP) p->typf=t=POINTER;
  206.                     p->code=c=ASSIGN;p->q2.flags=0;p->q2.val.vlong=sizetab[t&NQ];
  207.                     changed=1;
  208.                 }
  209.                 if(null&&(c==MULT||c==DIV||c==MOD||c==AND)){
  210.                     if(c==DIV||c==MOD){ err_ic=p;error(210);err_ic=0;}
  211.                     if(DEBUG&1024){ printf("operation converted to ASSIGN 0:\n");pric2(stdout,p);}
  212.                     o.val.vlong=l2zl(0L);eval_const(&o.val,LONG);
  213.                     insert_const2(&p->q1.val,t);p->q1.flags=KONST;
  214.                     p->code=c=ASSIGN;p->q2.flags=0;p->q2.val.vlong=sizetab[t&NQ];
  215.                     changed=1;
  216.                 }
  217.                 if(((t&NQ)<=LONG||fp_assoc)&&(c==ADD||c==ADDI2P||c==MULT||c==LSHIFT||c==RSHIFT||c==OR||c==AND)){
  218.                 /*  assoziative Operatoren  */
  219.                     struct IC *n=p->next;
  220.                     if(n&&n->code==c&&(n->q2.flags&KONST)&&n->typf==t&&n->q1.flags==p->z.flags&&n->q1.v==p->z.v&&zleqto(n->q1.val.vlong,p->z.val.vlong)){
  221.                         if(p->q1.flags==p->z.flags&&p->q1.v==p->z.v&&zleqto(p->q1.val.vlong,p->z.val.vlong)){
  222.                             if(n->q1.flags==n->z.flags&&n->q1.v==n->z.v&&zleqto(n->q1.val.vlong,n->z.val.vlong)){
  223.                                 if(DEBUG&1024){ printf("using associativity with:\n");pric2(stdout,p);pric2(stdout,p->next);}
  224.                                 n->q1=p->q1;
  225.                                 if(c==LSHIFT||c==RSHIFT||c==ADDI2P)
  226.                                     calc(ADD,t,&p->q2.val,&n->q2.val,&n->q2.val,0);
  227.                                 else
  228.                                     calc(c,t,&p->q2.val,&n->q2.val,&n->q2.val,0);
  229.                                 changed=1;
  230.                                 if(DEBUG&1024) printf("must remove first operation\n");
  231.                                 n=p;p=p->next;
  232.                                 if(have_alias){ free(n->use_list); free(n->change_list); }
  233.                                 remove_IC(n);continue;
  234.                             }
  235.                         }else{
  236.                             if(DEBUG&1024){ printf("using associativity with:\n");pric2(stdout,p);pric2(stdout,p->next);}
  237.                             n->q1=p->q1;
  238.                             if(c==LSHIFT||c==RSHIFT||c==ADDI2P)
  239.                                 calc(ADD,t,&p->q2.val,&n->q2.val,&n->q2.val,0);
  240.                             else
  241.                                 calc(c,t,&p->q2.val,&n->q2.val,&n->q2.val,0);
  242.                             changed=1;
  243.                         }
  244.                     }
  245.                 }
  246.                 if((c==ADDI2P||c==SUBIFP)&&(p->q1.flags&VARADR)){
  247.                 /*  add #var,#const -> move #var+const      */
  248.                     union atyps val;
  249.                     if(DEBUG&1024){printf("add/sub #var,#const changed to assign:\n");pric2(stdout,p);}
  250.                     eval_const(&p->q2.val,t);
  251.                     insert_const2(&val,LONG);
  252.                     if(c==ADDI2P) calc(ADD,LONG,&p->q1.val,&val,&p->q1.val,0);
  253.                         else      calc(SUB,LONG,&p->q1.val,&val,&p->q1.val,0);
  254.                     p->code=c=ASSIGN;
  255.                     p->q2.flags=0;
  256.                     p->typf=t=POINTER;
  257.                     p->q2.val.vlong=sizetab[t&NQ];
  258.                     changed=1;
  259.                 }
  260.                 if((c==ADD||c==SUB)&&(t&NQ)<=LONG&&p->next&&p->next->next){
  261.                     struct IC *p1=p->next,*p2=p1->next;
  262.                     if(p1->code==MULT&&p2->code==ADDI2P&&
  263.                        p1->typf==t&&p2->typf==t&&
  264.                        (p1->q2.flags&KONST)&&(p->z.flags&(SCRATCH|DREFOBJ))==SCRATCH&&(p1->z.flags&(SCRATCH|DREFOBJ))==SCRATCH&&
  265.                        !compare_objs(&p->z,&p1->q1,t)&&
  266.                        !compare_objs(&p1->z,&p2->q2,t)){
  267.                         if(DEBUG&1024){ printf("rearranging array-access:\n");pric2(stdout,p);pric2(stdout,p1);pric2(stdout,p2);}
  268.                         p1->q1=p->q1;
  269.                         p->q1=p2->q1;
  270.                         p2->q1=p2->z;
  271.                         p->z=p2->z;
  272.                         calc(MULT,t,&p->q2.val,&p1->q2.val,&p->q2.val,0);
  273.                         if(c==ADD) p->code=ADDI2P; else p->code=SUBIFP;
  274.                         changed=1;continue;
  275.                     }
  276.                 }
  277.             }
  278.             if(p->q1.flags&KONST){
  279.             /*  algebraische Optimierungen  */
  280.                 eval_const(&p->q1.val,t);
  281.                 if(zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))&&zdeqto(vdouble,d2zd(0.0))) null=1; else null=0;
  282.                 if(null&&(c==DIV||c==MOD||c==LSHIFT||c==RSHIFT)){
  283.                     if(DEBUG&1024){ printf("operation converted to ASSIGN 0:\n");pric2(stdout,p);}
  284.                     o.val.vlong=l2zl(0L);eval_const(&o.val,LONG);
  285.                     insert_const2(&p->q1.val,t);p->q1.flags=KONST;
  286.                     p->code=c=ASSIGN;p->q2.flags=0;p->q2.val.vlong=sizetab[t&NQ];
  287.                     changed=1;
  288.                 }
  289.             }
  290.             if(!USEQ2ASZ&&p->z.flags&&!compare_objs(&p->q2,&p->z,p->typf)){
  291.                 if(c==ADD||c==MULT||(c>=OR&&c<=AND)){
  292.                     struct obj o;
  293.                     if(DEBUG&1024){printf("swapping objs because USEQ2ASZ\n");pric2(stdout,p);}
  294.                     o=p->q2;p->q2=p->q1;p->q1=o;
  295.                     /*  kein changed hier!  */
  296.                 }else{pric2(stdout,p); ierror(0);}
  297.             }
  298.             if((c==ADD||c==SUB)&&p->next){
  299.                 struct IC *p1=p->next;
  300.                 if(p1->code==ADDI2P&&p1->typf==t&&(p->z.flags&(SCRATCH|DREFOBJ))==SCRATCH&&!compare_objs(&p->z,&p1->q2,t)){
  301.                     if(DEBUG&1024){ printf("rearranging array-access:\n");pric2(stdout,p);pric2(stdout,p1);}
  302.                     p1->q2=p->q1;
  303.                     p->q1=p1->q1;
  304.                     p->z=p1->z;
  305.                     p1->q1=p1->z;
  306.                     if(c==ADD) p->code=c=ADDI2P; else p->code=c=SUBIFP;
  307.                     changed=1;continue;
  308.                 }
  309.             }
  310.             if((c==SUB||c==DIV||c==MOD)&&!compare_objs(&p->q1,&p->q2,p->typf)){
  311.                 /*  x-x=0, x/x=1, x%x=0 */
  312.                 if(DEBUG&1024){ printf("i-i, i/i, i%%i converted to ASSIGN 0/1:\n");pric2(stdout,p);}
  313.                 if(c==DIV) o.val.vlong=l2zl(1L); else o.val.vlong=l2zl(0L);
  314.                 eval_const(&o.val,LONG);insert_const2(&p->q1.val,t);p->q1.flags=KONST;
  315.                 p->code=c=ASSIGN;p->q2.flags=0;p->q2.val.vlong=sizetab[t&NQ];
  316.                 changed=1;
  317.             }
  318.             if(c==ASSIGN&&(p->z.flags&VAR)&&p->z.flags==p->q1.flags&&p->z.v==p->q1.v&&zleqto(p->z.val.vlong,p->q1.val.vlong)){
  319.                 struct IC *d;
  320.                 if(DEBUG&1024){ printf("removing redundant move:\n");pric2(stdout,p);}
  321.                 changed=1;
  322.                 d=p; p=p->next;
  323.                 if(have_alias){ free(d->use_list); free(d->change_list);}
  324.                 remove_IC(d); continue;
  325.             }
  326.             if(c>=BEQ&&c<=BGT){
  327.               struct IC *p2=p->prev;
  328.               if(p2&&p2->code==COMPARE&&!compare_objs(&p->q1,&p2->z,0)){
  329.                 struct IC *p3=p2->prev;
  330.                 if(p3&&p3->code==c){
  331.                   struct IC *p4=p3->prev;
  332.                   if(p4->code==COMPARE&&!compare_objs(&p3->q1,&p4->z,0)
  333.                      &&!compare_objs(&p2->q1,&p4->q1,p4->typf)&&!compare_objs(&p2->q2,&p4->q2,p4->typf)){
  334.                     if(DEBUG&1024){printf("removing redundant compare\n");pric(stdout,p2);pric2(stdout,p);}
  335.                     p->code=NOP;
  336.                     p2->code=NOP;
  337.                     changed=1;
  338.                   }
  339.                 }
  340.               }
  341.             }
  342.             p=p->next;
  343.         }
  344.         if(changed) done|=changed;
  345.         gchanged|=changed;
  346.     }while(changed);
  347.     return(done);
  348. }
  349.  
  350. void insert_loads()
  351. /*  Laedt Speicher in temporaere Variablen */
  352. {
  353.   struct IC *p,*new;
  354.   struct Typ t={0};
  355.   if(DEBUG&1024) printf("insert_loads()\n");
  356.   for(p=first_ic;p;p=p->next){
  357.     if(p->q2.flags){
  358.       if(p->q1.flags&DREFOBJ){
  359.         new=mymalloc(ICS);
  360.         new->code=ASSIGN;
  361.         new->typf=p->typf;
  362.         new->q1.am=new->q2.am=new->z.am;
  363.         new->q1=p->q1;
  364.         new->q2.flags=0;
  365.         new->q2.val.vlong=sizetab[p->typf&NQ];
  366.         new->z.flags=VAR;
  367.         new->z.val.vlong=l2zl(0L);
  368.         t.flags=p->typf;
  369.         new->z.v=add_tmp_var(clone_typ(&t));
  370.         insert_IC(p->prev,new);
  371.         p->q1=new->z;
  372.       }
  373.       if(p->q2.flags&DREFOBJ){
  374.         new=mymalloc(ICS);
  375.         new->code=ASSIGN;
  376.         new->typf=p->typf;
  377.         new->q1.am=new->q2.am=new->z.am;
  378.         new->q1=p->q2;
  379.         new->q2.flags=0;
  380.         new->q2.val.vlong=sizetab[p->typf&NQ];
  381.         new->z.flags=VAR;
  382.         new->z.val.vlong=l2zl(0L);
  383.         t.flags=p->typf;
  384.         new->z.v=add_tmp_var(clone_typ(&t));
  385.         insert_IC(p->prev,new);
  386.         p->q2=new->z;
  387.       }
  388.     }
  389.   }
  390. }
  391.  
  392. void insert_ccs(void)
  393. /*  Fuegt Variablen fuer ccs ein.   */
  394. {
  395.     struct IC *p; struct Var *v; struct Typ *t;
  396.     if(DEBUG&1024) printf("insert_ccs()\n");
  397.     for(p=first_ic;p;p=p->next){
  398.         if(p->code==COMPARE||p->code==TEST){
  399.             p->z.flags=VAR;
  400.             p->z.val.vlong=l2zl(0L);
  401.             t=mymalloc(TYPS);
  402.             t->flags=0;
  403.             t->next=0;
  404.             v=add_tmp_var(t);
  405.             p->z.v=v;
  406.             p=p->next;
  407.             if(p->code<BEQ||p->code>BGT){
  408.                 p=p->prev;
  409.                 p->code=NOP;
  410.                 p->q1.flags=p->q2.flags=p->z.flags=0;
  411.             }else{
  412.                 p->q1.flags=VAR;
  413.                 p->q1.val.vlong=l2zl(0L);
  414.                 p->q1.v=v;
  415.             }
  416.         }
  417.     }
  418. }
  419.  
  420. #endif
  421. #define FREEAV free(av_globals);free(av_statics);free(av_drefs);free(av_address);
  422. void optimize(long flags,struct Var *function)
  423. /*  flags:   1=Register, 2=optimize, 4=cse/cp, 8=constant_propagation,  */
  424. /*          16=dead_assignments, 32=global-optimizations                */
  425. /*          64=blockweise Registervergabe, 128=loop_optimizations (nur  */
  426. /*             in Verbindung mit 32), 256=recalc_offsets                */
  427. {
  428. #ifndef NO_OPTIMIZER
  429.     struct flowgraph *fg=0;int r,pass=0;
  430.     if(!function) ierror(0);
  431.     norek=nocall=0;
  432.     report_suspicious_loops=report_weird_code=1;
  433.     if(!strcmp(function->identifier,"main")){norek=1;nocall=1;}
  434.     /*  falls main() rekursiv aufgerufen werden kann, muss nomain==0 sein   */
  435.  
  436. #else
  437.  
  438.     flags&=1;
  439.  
  440. #endif
  441.     if(flags&2){
  442. #ifndef NO_OPTIMIZER
  443.         /*  Variablen fuer ccs einsetzen.   */
  444.         if(multiple_ccs) insert_ccs();
  445.         /*  Speicherzugriffe in extra tmp-Vars umleiten, wegen cse */
  446.         if(flags&4) insert_loads();
  447.         /*  nur ein pass, wenn nur lokale Optimierungen */
  448.         if(!(flags&32)) maxoptpasses=1;
  449.         do{
  450.             gchanged=0;pass++;
  451.             av_globals=av_statics=av_address=av_drefs=0;
  452.             rd_globals=rd_statics=rd_address=rd_drefs=0;
  453.             ae_globals=ae_statics=ae_address=ae_drefs=0;
  454.             cp_globals=cp_statics=cp_address=cp_drefs=0;
  455.             dlist=0;vilist=0;elist=0;rd_parms=0;
  456.  
  457.             if(DEBUG&1024) printf("\noptimizer (function %s) pass %d\n",function->identifier,pass);
  458.             num_vars();
  459.             peephole();
  460.             fg=jump_optimization();
  461.             create_alias(fg);
  462.             if(DEBUG&2048) print_vi();
  463.             if(flags&8){
  464.                 do{
  465.                     num_defs();
  466.                     if(flags&32){
  467.                         rd_mode=0;
  468.                         reaching_definitions(fg);
  469.                         if(DEBUG&1024) print_flowgraph(fg);
  470.                     }
  471.                     r=constant_propagation(fg,flags&32);
  472.                     if(DEBUG&1024) {printf("constant_propagation returned %d\n",r);print_flowgraph(fg);}
  473.                     if(r){
  474.                         if(peephole()){free_flowgraph(fg);fg=jump_optimization();}
  475.                     }
  476.                 }while(r);
  477.             }
  478.             if(flags&4){
  479.                 int repeat;
  480.                 do{
  481.                     do{
  482.                         num_exp();
  483.                         if(DEBUG&1024) print_flowgraph(fg);
  484.                         repeat=r=cse(fg,0);    /*  local cse   */
  485.                         if(DEBUG&1024) printf("local cse returned %d\n",r);
  486.                         gchanged|=r;
  487.                         if(r){  /*  neue Variablen eingefuegt   */
  488.                             if(DEBUG&1024) printf("must repeat num_vars\n");
  489.                             free(vilist);
  490.                             FREEAV;
  491.                             num_vars();
  492.                         }
  493.                         do{
  494.                             num_copies();
  495.                             if(DEBUG&1024) print_flowgraph(fg);
  496.                             r=copy_propagation(fg,0);   /*  copy propagation    */
  497.                             if(DEBUG&1024) printf("local copy propagation returned %d\n",r);
  498.                             if(r&2){
  499.                                 if(DEBUG&1024) printf("must repeat num_vars\n");
  500.                                 free(vilist);
  501.                                 FREEAV;
  502.                                 num_vars();
  503.                             }
  504.                             gchanged|=r;repeat|=r;
  505.                         }while(r);
  506.                     }while(repeat);
  507.                     repeat=0;
  508.                     if(flags&32){
  509.                         num_exp();
  510.                         if(DEBUG&1024) print_flowgraph(fg);
  511.                         available_expressions(fg);
  512.                         if(DEBUG&1024) print_flowgraph(fg);
  513.                         r=cse(fg,1);gchanged|=r;repeat|=r;
  514.                         if(DEBUG&1024) printf("global cse returned %d\n",r);
  515.                         if(r){  /*  neue Variablen eingefuegt   */
  516.                             if(DEBUG&1024) printf("must repeat num_vars\n");
  517.                             free(vilist);
  518.                             FREEAV;
  519.                             num_vars();
  520.                             gchanged|=r;repeat|=r;
  521.                             do{
  522.                                 num_copies();
  523.                                 if(DEBUG&1024) print_flowgraph(fg);
  524.                                 r=copy_propagation(fg,0);   /*  copy propagation    */
  525.                                 if(DEBUG&1024) printf("local copy propagation returned %d\n",r);
  526.                                 if(r&2){
  527.                                     if(DEBUG&1024) printf("must repeat num_vars\n");
  528.                                     free(vilist);
  529.                                     FREEAV;
  530.                                     num_vars();
  531.                                 }
  532.                                 gchanged|=r;repeat|=r;
  533.                             }while(r);
  534.                         }
  535.                         num_copies();
  536.                         available_copies(fg);
  537.                         if(DEBUG&1024) print_flowgraph(fg);
  538.                         r=copy_propagation(fg,1);   /*  copy propagation    */
  539.                         if(DEBUG&1024) printf("global copy propagation returned %d\n",r);
  540.                         if(r&2){
  541.                             if(DEBUG&1024) printf("must repeat num_vars\n");
  542.                             free(vilist);
  543.                             FREEAV;
  544.                             num_vars();
  545.                         }
  546.                         gchanged|=r;repeat|=r;
  547.                     }
  548.                 }while(0/*repeat*/);
  549.             }
  550.             if((flags&160)==160){
  551.                 r=loop_optimizations(fg);
  552.                 gchanged|=r;
  553.                 fg=jump_optimization();
  554.             }
  555.             if((flags&16)||((flags&1)&&pass>=maxoptpasses)){
  556. /*                num_vars();*/
  557.                 free_alias(fg);
  558.                 create_alias(fg);
  559.                 active_vars(fg);
  560.                 if(DEBUG&1024) print_flowgraph(fg);
  561.                 if((flags&16)&&pass<=maxoptpasses){
  562.                     r=dead_assignments(fg);
  563.                     if(DEBUG&1024) printf("dead_assignments returned %d\n",r);
  564.                     gchanged|=r;
  565.                 }
  566.             }
  567.  
  568.  
  569.             if((!gchanged||pass>=maxoptpasses)){
  570.             /*  Funktion evtl. fuer inlining vorbereiten und    */
  571.             /*  Registervergabe                                 */
  572.                 int varargs=0,c;
  573.                 if((c=function->vtyp->exact->count)!=0&&(*function->vtyp->exact->sl)[c-1].styp->flags!=VOID)
  574.                     varargs=1;
  575.  
  576.                 /*  default-Wert fuer inline-Entscheidung   */
  577.                 if(!varargs&&(flags&4096)&&(only_inline||ic_count<=inline_size)){
  578.                 /*  fuer function inlinig vorbereiten   */
  579.                     struct IC *p,*new;
  580.                     if(DEBUG&1024) printf("function <%s> prepared for inlining(ic_count=%d)\n",function->identifier,ic_count);
  581.                     function->fi=new_fi();
  582.                     function->fi->first_ic=first_ic;
  583.                     function->fi->last_ic=last_ic;
  584.                     first_ic=last_ic=0;
  585.                     p=function->fi->first_ic;
  586.                     while(p){
  587.                         new=mymalloc(ICS);
  588.                         memcpy(new,p,ICS);
  589.                         if((p->code>=BEQ&&p->code<=BRA)||p->code==LABEL)
  590.                             new->typf-=lastlabel;
  591.                         add_IC(new);
  592.                         p=p->next;
  593.                     }
  594.                     p=first_ic;first_ic=function->fi->first_ic;function->fi->first_ic=p;
  595.                     p=last_ic;last_ic=function->fi->last_ic;function->fi->last_ic=p;
  596.                     function->fi->vars=0;
  597.                 }
  598.                 if(flags&1){
  599.                   local_combine(fg);
  600.                   if(DEBUG&1024) print_flowgraph(fg);
  601.                   local_regs(fg);
  602.                   if(DEBUG&1024) print_flowgraph(fg);
  603.                   loops(fg,1);
  604.                   if(DEBUG&1024) print_flowgraph(fg);
  605.                   fg=create_loop_headers(fg,1);
  606.                   if(DEBUG&1024) print_flowgraph(fg);
  607.                   fg=create_loop_footers(fg,1);
  608.                   if(DEBUG&1024) print_flowgraph(fg);
  609.                   loop_regs(fg);
  610.                   if(DEBUG&1024) print_flowgraph(fg);
  611. #if 0
  612.                   if(flags&64){
  613.                     block_regs(fg);
  614.                     if(DEBUG&1024) print_flowgraph(fg);
  615.                   }
  616. #endif
  617.                   insert_regs(fg);
  618.                 }
  619.                 if(flags&256) recalc_offsets(fg);
  620.             }
  621.  
  622.             free_alias(fg);
  623.             free_flowgraph(fg);
  624.             free(vilist);
  625.             FREEAV;
  626.  
  627.             if((flags&32)&&gchanged&&pass>=maxoptpasses) error(172,maxoptpasses);
  628.  
  629.         }while(gchanged&&pass<maxoptpasses);
  630.  
  631.         /*  nur, um nochmal ueberfluessige Labels zu entfernen  */
  632.         fg=construct_flowgraph();
  633.         free_flowgraph(fg);
  634.  
  635.         /*  Register bei Funktionsaufrufen sichern  */
  636.         insert_saves();
  637.  
  638. #endif
  639.  
  640.     }else{
  641.         /*  keine Optimierungen     */
  642.         if(flags&1) simple_regs();
  643.         load_simple_reg_parms();
  644.     }
  645.     lastlabel=label;
  646. }
  647.  
  648.